﻿using Microsoft.AspNetCore.Mvc.Filters;
using PlutoStudio.AspNetCore.Configuration;
using PlutoStudio.AspNetCore.Mvc.Extensions;
using PlutoStudio.Aspects;
using PlutoStudio.Dependency;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace PlutoStudio.AspNetCore.Mvc.Validation
{
    public class ValidationActionFilter : IAsyncActionFilter, ITransientDependency
    {
        private readonly IIocResolver _iocResolver;
        private readonly IAspNetCoreConfiguration _configuration;

        public ValidationActionFilter(IIocResolver iocResolver, IAspNetCoreConfiguration configuration)
        {
            _iocResolver = iocResolver;
            _configuration = configuration;
        }

        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            if (!_configuration.IsValidationEnabledForControllers || !context.ActionDescriptor.IsControllerAction())
            {
                await next();
                return;
            }

            using (CrossCuttingConcerns.Applying(context.Controller, CrossCuttingConcerns.Validation))
            {
                using (var validator = _iocResolver.ResolveAsDisposable<MvcActionInvocationValidator>())
                {
                    validator.Value.Initialize(context);
                    validator.Value.Validate();
                }

                await next();
            }
        }
    }
}
